"use client";
import React, { createContext, useContext, useState, useCallback, useEffect } from "react";
import { get, post } from "@/lib/request";
import { toast } from "sonner";
import { useSocket } from "./socketContext";

export interface Message {
  id: string;
  content: string;
  senderId: string;
  createdAt: string;
  conversationId: string;
  type: 'TEXT' | 'IMAGE' | 'FILE' | 'VOICE' | 'SYSTEM';
  sender: {
    id: string;
    username: string;
    avatar?: string;
  };
}

export interface Conversation {
  id: string;
  type: "private" | "group"; // 私聊 ｜ 群聊
  name: string;
  avatar: string | null;
  participants?: Array<{ id: string; username: string; avatar?: string }>;
  lastMessage?: {
    content: string;
    createdAt: string;
    sender: {
      username: string;
    }
  };
  unreadCount?: number;
  // for private chat
  friend?: {
    id: string;
    username: string;
    avatar: string | null;
  }
}

interface ConversationContextType {
  conversations: Conversation[];
  fetchConversations: () => Promise<void>;
  currentConversation: Conversation | null;
  setCurrentConversation: (c: Conversation | null) => void;
  startConversation: (friend: { id: string; username: string; avatar: string | null; }) => void;
  messages: Message[];
  addMessage: (message: Message) => void;
  fetchMoreMessages: () => Promise<void>;
  hasMoreMessages: boolean;
  isMessagesLoading: boolean;
}

const ConversationContext = createContext<ConversationContextType | undefined>(undefined);

// 聊天上下文
export const ConversationProvider = ({ children }: { children: React.ReactNode }) => {
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [currentConversation, setCurrentConversation] = useState<Conversation | null>(null);
  const [messages, setMessages] = useState<Message[]>([]);
  const [isMessagesLoading, setMessagesLoading] = useState(false);
  const [hasMoreMessages, setHasMoreMessages] = useState(true);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const { socket } = useSocket();

  const fetchConversations = useCallback(async () => {
    try {
      const res = await get('/conversations');
      if (res.data) {
        setConversations(res.data);
      }
    } catch (error) {
      toast.error('获取会话列表失败');
    }
  }, []);

  const startConversation = useCallback(async (friend: { id: string; username: string; avatar: string | null; }) => {
    try {
      // 请求后端来查找或创建会话
      const res = await post('/conversations', { targetUserId: friend.id });
      const conversationFromServer = res.data;

      if (!conversationFromServer) {
        throw new Error('无法开始会话');
      }

      // 使用从服务器获取的会话信息
      const existingConv = conversations.find(c => c.id === conversationFromServer.id);
      
      if (existingConv) {
        setCurrentConversation(existingConv);
      } else {
        // 如果会话在本地不存在，则格式化并添加到列表
        const newConv: Conversation = {
          id: conversationFromServer.id,
          type: 'private',
          name: friend.username, // 使用friend的name和avatar来即时显示
          avatar: friend.avatar,
          participants: [{ id: friend.id, username: friend.username, avatar: friend.avatar || undefined }],
          friend: friend,
        };
        setConversations(prev => [newConv, ...prev.filter(p => p.id !== newConv.id)]);
        setCurrentConversation(newConv);
      }
      
    } catch (error: any) {
      toast.error(error.message || '开始会话失败');
    }
  }, [conversations]);

  const addMessage = useCallback((message: Message) => {
    // 如果新消息属于当前会话，则更新消息列表
    if (message.conversationId === currentConversation?.id) {
      setMessages(prev => [...prev, message]);
    }

    // 更新会话列表中的最后一条消息和时间
    setConversations(prev => {
      const updatedConversations = prev.map(conv => {
        if (conv.id === message.conversationId) {
          return {
            ...conv,
            lastMessage: {
              content: message.content,
              createdAt: message.createdAt,
              sender: {
                username: message.sender.username
              }
            },
            unreadCount: (conv.id === currentConversation?.id) ? 0 : (conv.unreadCount || 0) + 1
          };
        }
        return conv;
      });

      // 将有新消息的会话置顶
      const targetConv = updatedConversations.find(c => c.id === message.conversationId);
      if (targetConv) {
        const otherConvs = updatedConversations.filter(c => c.id !== message.conversationId);
        return [targetConv, ...otherConvs];
      }
      
      return updatedConversations;
    });
  }, [currentConversation?.id]);

  const fetchMessages = useCallback(async (conversationId: string, cursor: string | null) => {
    const isInitialFetch = cursor === null;
    if (isInitialFetch) {
      setMessagesLoading(true);
      setMessages([]);
      setNextCursor(null);
    }

    try {
      const params = new URLSearchParams();
      params.append('conversationId', conversationId);
      if (cursor) {
        params.append('cursor', cursor);
      }
      
      const res = await get(`/messages/history?${params.toString()}`);
      const data = res.data;

      if (!data) throw new Error('获取历史消息失败');

      const newMessages = data.messages || [];

      setMessages(prev => isInitialFetch ? newMessages : [...newMessages, ...prev]);
      setNextCursor(data.nextCursor);
      setHasMoreMessages(data.nextCursor !== null);

    } catch (error) {
      toast.error('获取历史消息失败');
    } finally {
      if (isInitialFetch) {
        setMessagesLoading(false);
      }
    }
  }, []);

  const fetchMoreMessages = useCallback(async () => {
    if (!currentConversation || !nextCursor || isMessagesLoading) return;
    
    setMessagesLoading(true);
    await fetchMessages(currentConversation.id, nextCursor);
    setMessagesLoading(false);

  }, [currentConversation, nextCursor, isMessagesLoading, fetchMessages]);

  // 监听新消息
  useEffect(() => {
    if (!socket) return;

    socket.on('new_message', (message: Message) => {
      addMessage(message);
    });

    return () => {
      socket.off('new_message');
    };
  }, [socket, addMessage]);

  // 切换会话时加载历史消息
  useEffect(() => {
    if (!currentConversation) {
      setMessages([]);
      return;
    }

    // 点击会话时，清空未读数
    setConversations(prev => prev.map(conv => 
      conv.id === currentConversation.id ? { ...conv, unreadCount: 0 } : conv
    ));

    const loadInitialMessages = async () => {
      setHasMoreMessages(true);
      setNextCursor(null);
      await fetchMessages(currentConversation.id, null);
    };

    loadInitialMessages();
  }, [currentConversation, fetchMessages]);

  return (
    <ConversationContext.Provider value={{
      conversations,
      fetchConversations,
      currentConversation,
      setCurrentConversation,
      startConversation,
      messages,
      addMessage,
      fetchMoreMessages,
      hasMoreMessages,
      isMessagesLoading
    }}>
      {children}
    </ConversationContext.Provider>
  );
};

export function useConversation() {
  const ctx = useContext(ConversationContext);
  if (!ctx) throw new Error("useConversation 必须在 ConversationProvider 內使用");
  return ctx;
} 